package com.gosling.gosling;

import cn.hutool.core.bean.BeanUtil;
import com.gosling.cloudspace.common.entity.dtos.OrderInfoDto;
import com.gosling.cloudspace.common.entity.dtos.TestDao;
import com.gosling.cloudspace.tools.CglibDynamicProxy;
import org.springframework.cglib.beans.BeanGenerator;
import org.springframework.cglib.beans.BeanMap;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SysCglibOrJdkProxyTest {
   public static void main(String[] args) {
      jdkProxy();
      cglibP();
   }

   private static void jdkProxy() {
      Proxy.newProxyInstance(SysCglibOrJdkProxyTest.class.getClassLoader(), new Class[]{TestDao.class},
              new InvocationHandler() {
                 @Override
                 public Object invoke(Object proxy, Method method, Object[] args1) throws Throwable {
                    System.out.println("JDK动态代理测试: " + method.getName());
                    return null;
                 }
              });
   }

   /**
    * 使用cgLib为实体类添加字段
    *
    * @author: osc_lihonglin
    * @date: 2024/4/8 17:32
    */
   private static void cglibProxyInstance() {
      OrderInfoDto obj = new OrderInfoDto();
      obj.setOrderName("order");
      obj.setPayMoney("pay");
      Class clazz = obj.getClass();
      //为实体类添加字段
      BeanGenerator beanGenerator = new BeanGenerator();
      beanGenerator.setSuperclass(clazz);
      for (Field field : clazz.getDeclaredFields()) {
         field.setAccessible(true);
         //添加字段 举例为中文字段
         beanGenerator.addProperty(field.getName() + "Dic", String.class);
      }
      //创建代理对象[cglib动态代理]
      Object proxyInstance = beanGenerator.create();
      BeanUtil.copyProperties(clazz, proxyInstance);
      //为新增字段设置值
      BeanMap beanMap = BeanMap.create(proxyInstance);
      //只有在map里面能打印，在实体类里面不能打印
      //前提是需要把实体类里面添加Dic字段，就可以打印
      //如果不添加字段表，响应给前端也是能展示的
      System.out.println(beanMap);
      //{payMoney=null, payMoneyDic=null, orderNameDic=null, orderName=null}
      System.out.println(proxyInstance);
      //OrderInfoDto(orderName=null, payMoney=null)
   }

   private static void cglibP() {
      //创建代理对象
      CglibDynamicProxy cdp = new CglibDynamicProxy();
      //创建目标对象
      TestDao testDao = new TestDao();
      //获取增强后的目标对象
      TestDao testDaoAdvice = (TestDao) cdp.createProxy(testDao);
      //执行方法
      testDaoAdvice.save();
      System.out.println("==============");
      testDaoAdvice.modify();
      System.out.println("==============");
      testDaoAdvice.delete();
   }
}
